<template>
  <div>
    <div class="flex justify-between p-2 mt-2">
      <el-button type="primary" plain icon="Plus" @click="handleAdd(0)" v-permission="['system.menu.add']"
        >新增</el-button
      >
      <el-tooltip effect="dark" content="刷新" placement="top">
        <el-button circle icon="RefreshLeft" @click="fetchMenuList" />
      </el-tooltip>
    </div>
    <div class="p-2 mt-1 rounded">
      <el-table
        :data="menuList"
        style="width: 100%; margin-bottom: 20px"
        row-key="menuId"
        v-loading="loading"
      >
        <el-table-column prop="menuName" label="菜单名" width="140" />
        <el-table-column prop="icon" label="图标" align="center" width="100">
          <template #default="scope">
            <el-icon :size="18" v-if="scope.row.icon">
              <component :is="scope.row.icon" />
            </el-icon>
          </template>
        </el-table-column>
        <el-table-column prop="orderNum" label="排序" />
        <el-table-column prop="path" label="路由" />
        <el-table-column prop="component" label="组件路径" width="200" />
        <el-table-column prop="perms" label="权限标识" />
        <el-table-column label="菜单类型">
          <template #default="scope">
            <DictTag :list="sys_menu_type" :dictKey="scope.row.menuType" />
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态">
          <template #default="scope">
            <DictTag :list="sys_menu_status" :dictKey="scope.row.status" />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="210">
          <template #default="scope">
            <el-button
              type="primary"
              icon="Plus"
              link
              @click="handleAdd(scope.row.menuId)"
              v-permission="['system.menu.add']"
              >新增</el-button
            >
            <el-button
              type="primary"
              icon="Edit"
              link
              @click="handleEdit(scope.row)"
              v-permission="['system.menu.edit']"
              >修改</el-button
            >
            <el-button
              type="primary"
              icon="Delete"
              link
              @click="handleDelete(scope.row)"
              v-permission="['system.menu.remove']"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </div>
    <el-dialog
      :title="dialogTitle"
      v-model="dialogVisible"
      width="680px"
      :before-close="resetForm"
    >
      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
        <el-row>
          <el-col :span="24">
            <el-form-item label="上级菜单">
              <el-tree-select
                v-model="form.parentId"
                :data="treeMenuList"
                :props="{
                  value: 'menuId',
                  label: 'menuName',
                  children: 'children',
                }"
                value-key="menuId"
                placeholder="选择上级菜单"
                check-strictly
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="菜单类型" prop="menuType">
              <el-radio-group v-model="form.menuType">
                <el-radio value="M">目录</el-radio>
                <el-radio value="C">菜单</el-radio>
                <el-radio value="F">按钮</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.menuType != 'F'">
            <el-form-item label="菜单图标" prop="icon">
              <el-popover placement="bottom-start" :width="540" trigger="click">
                <template #reference>
                  <el-input
                    v-model="form.icon"
                    placeholder="点击选择图标"
                    readonly
                  >
                    <template #prefix>
                      <el-icon
                        :size="18"
                        v-if="form.icon"
                        style="height: 32px; width: 16px"
                      >
                        <component :is="form.icon" />
                      </el-icon>
                    </template>
                  </el-input>
                </template>
                <div>
                  <el-input
                    v-model="iconSearchValue"
                    clearable
                    placeholder="请输入图标名称"
                    @clear="filterIcons"
                    @input="filterIcons"
                  >
                    <template #suffix
                      ><i class="el-icon-search el-input__icon"
                    /></template>
                  </el-input>
                </div>
                <div class="list-container">
                  <div
                    v-for="item in originIconList"
                    @click="selectIcon(item)"
                    class="icon-item"
                  >
                    <div>
                      <el-icon style="height: 32px; width: 16px">
                        <component :is="item" />
                      </el-icon>
                      <span class="ml-1">{{ item }}</span>
                    </div>
                  </div>
                </div>
              </el-popover>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="显示排序" prop="orderNum">
              <el-input-number v-model="form.orderNum" :min="0" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单名称" prop="menuName">
              <el-input v-model="form.menuName" placeholder="请输入菜单名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.menuType != 'F'">
            <el-form-item prop="path">
              <template #label>
                <span>
                  <el-tooltip
                    content="访问的路由地址，如：`user`"
                    placement="top"
                  >
                    <el-icon><question-filled /></el-icon>
                  </el-tooltip>
                  路由地址
                </span>
              </template>
              <el-input v-model="form.path" placeholder="请输入路由地址" />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.menuType == 'C'">
            <el-form-item prop="component">
              <template #label>
                <span>
                  <el-tooltip
                    content="访问的组件路径，如：`system/user/index`，默认在`views`目录下"
                    placement="top"
                  >
                    <el-icon><question-filled /></el-icon>
                  </el-tooltip>
                  组件路径
                </span>
              </template>
              <el-input v-model="form.component" placeholder="请输入组件路径" />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.menuType != 'M'">
            <el-form-item>
              <el-input
                v-model="form.perms"
                placeholder="请输入权限标识"
                maxlength="100"
              />
              <template #label>
                <span>
                  <el-tooltip
                    content='控制器中定义的权限字符，如：@SaCheckPermission("system.xit")'
                    placement="top"
                  >
                    <el-icon><question-filled /></el-icon>
                  </el-tooltip>
                  权限字符
                </span>
              </template>
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.menuType == 'C'">
            <el-form-item>
              <el-input
                v-model="form.query"
                placeholder="请输入路由参数"
                maxlength="255"
              />
              <template #label>
                <span>
                  <el-tooltip
                    content='访问路由的默认传递参数，如：`{"id": 1, "name": "zs"}`'
                    placement="top"
                  >
                    <el-icon><question-filled /></el-icon>
                  </el-tooltip>
                  路由参数
                </span>
              </template>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item>
              <el-input
                v-model="form.title"
                placeholder="请输入i18国际化字段"
                maxlength="255"
              />
              <template #label>
                <span>
                  <el-tooltip
                    content="国际化访问字段，如：`system.menu`"
                    placement="top"
                  >
                    <el-icon><question-filled /></el-icon>
                  </el-tooltip>
                  国际化
                </span>
              </template>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm(formRef)"
            >确 定</el-button
          >
          <el-button @click="resetForm">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import { getMenuList, addMenu, updateMenu, deleteMenu } from "@/api/system/menu";
import useDict from "@/utils/dict";
import DictTag from "@/components/tag/DictTag.vue";
import { iconList } from "@/utils/icon";
import { ElMessageBox, ElMessage } from "element-plus";
const { sys_menu_type, sys_menu_status } = useDict(
  "sys_menu_type",
  "sys_menu_status"
);
const formRef = ref(null);
const submitType = ref("add");
const dialogVisible = ref(false);
const menuList = ref([]);
const dialogTitle = ref("");
const loading = ref(false);
const treeMenuList = ref([]);
const originIconList = ref([]);
originIconList.value = iconList;
const iconSearchValue = ref('');
const rules = ref({
  menuName: [{ required: true, message: "菜单名称不能为空", trigger: "blur" }],
  orderNum: [{ required: true, message: "菜单顺序不能为空", trigger: "blur" }],
  path: [{ required: true, message: "路由地址不能为空", trigger: "blur" }],
});
const form = ref({
  menuName: "",
  parentId: 0,
  orderNum: 0,
  path: "",
  component: "",
  query: "",
  menuType: "M",
  perms: "",
  icon: "",
  title: ""
});

function submitForm() {
  formRef.value.validate().then(async () => {
    if (submitType.value !== 'add') {
      await updateMenu(form.value);
    } else {
      await addMenu(form.value);
    }
    dialogVisible.value = false;
    resetForm();
    fetchMenuList();
  });
}

function resetForm() {
  form.value = {
    menuName: "",
    parentId: 0,
    orderNum: 0,
    path: "",
    component: "",
    query: "",
    menuType: "M",
    status: "",
    perms: "",
    icon: "",
    title: ""
  };
  dialogVisible.value = false;
}
function handleAdd(parentId) {
  form.value.parentId = parentId;
  submitType.value = 'add';
  dialogVisible.value = true;
  dialogTitle.value = "新增菜单";
}

function handleEdit(row) {
  form.value = row;
  submitType.value = 'edit';
  dialogVisible.value = true;
  dialogTitle.value = "修改菜单";
}

async function handleDelete(row) {
  ElMessageBox.confirm('确定删除吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    if(row.children.length > 0) {
      ElMessage.error('有下级菜单，不能直接删除');
      return;
    }else{
      await deleteMenu(row.menuId);
      fetchMenuList();
    }
  });
}

function filterIcons() {
  originIconList.value = iconList;
  if (iconSearchValue.value) {
    originIconList.value = iconList.filter(item => item.indexOf(iconSearchValue.value) !== -1)
  }
}

function selectIcon(item) {
  form.value.icon = item;
  document.body.click();
}

async function fetchMenuList() {
  loading.value = true;
  menuList.value = await getMenuList();
  const menu = { menuId: 0, menuName: "主类目", children: [] }
  menu.children = menuList.value;
  treeMenuList.value = [menu];
  loading.value = false;
}
onMounted(() => {
  fetchMenuList();
});
</script>

<style scoped>
.list-container {
  max-height: 200px;
  overflow: auto;
  display: flex;
  flex-wrap: wrap;
}
.icon-item {
  width: calc(100% / 3);
  height: 25px;
  line-height: 25px;
  cursor: pointer;
  display: flex;
}
.icon-item:hover {
  color: #409eff;
}
</style>
